import importlib
import os
import sys
import requests
import oss2
import time
import config

def find_modules_and_functions(path):
    modules_and_functions = list()
    sys.path.insert(0, path) ##防止导入出错
    for name in os.listdir(path):
        if os.path.isfile(os.path.join(path, name)):
            continue
        globals()[f'{os.path.basename(path)}_{name}'] = importlib.import_module(name)
        module = globals()[f'{os.path.basename(path)}_{name}']
        globals()[f'{os.path.basename(path)}_{name}'] = importlib.reload(module)
        modules_and_functions.append((f'{os.path.basename(path)}_{name}', [function for function in dir(module) if callable(getattr(module, function))]))
    return modules_and_functions

def add_url_to_bp(path, bp):
    modules_and_functions = find_modules_and_functions(path)
    for module, impls in modules_and_functions:
        if not module.endswith('impl'):
            name = module.split('_')[-1]
        else:
            name = module.split('_')[0]


        for impl in impls:
            ## avoid view function repeat
            url = f"{name}/{impl if impl.find('_') == -1  else '/'.join(impl.replace(f'{name}_', '').split('_'))}"
            ## remove _impl layer in route path
            url = url.replace('_impl', '')
            bp.add_url_rule(url, impl, getattr(globals()[module], impl))

    return bp

def download_to_local(image_url):
    os.makedirs('cache_imgs', exist_ok=True)
    res = requests.get(image_url)
    if res.status_code == 200:
        wname = f"cache_imgs/{image_url.split('/')[-1]}"
        with open(wname, 'wb') as w:
            w.write(res.content) 
        return wname
    else:
        logging.warning('文件下载失败')


def uploadfile(image_url):
    lfile = download_to_local(image_url)
    # 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
    auth = oss2.Auth(config.OSS_KEY,
                        config.OSS_SECRET)
    with open(lfile, 'rb') as fileobj:
        bucket = oss2.Bucket(
            auth, config.OSS_ENDPOINT, config.OSS_BUCKET)
        timestamp = time.strftime('%y%m%d%H%M%S',time.localtime())
        bucket.put_object(f'sd/{timestamp}.png', fileobj)
        return f'{config.OSS_URL}/{timestamp}.png'


import hashlib
import codecs
 
def gen_password(password, salt):
   # 将密码和盐值拼接成字节串
   data = (password + salt).encode('utf-8')
   # 使用SHA3 256算法进行哈希计算
   hash = hashlib.sha3_256(data)
   # 将哈希结果转换为十六进制字符串
   return hash.hexdigest()
 

import random
import string
 
def generate_salt(length=8):
   characters = string.ascii_letters + string.digits
   salt = ''.join(random.choices(characters, k=length))
   return salt


from PIL import Image, ImageDraw, ImageFont
import random
import string
import random
import io, base64
 
def generate_captcha_text(length=6):
    def generate_random_chinese():
        #code_point = random.randint(0x4E00, 0x9fa5)
        code_point = random.randint(0x4E00, 0x4E00+1000)
        chinese_char = chr(code_point)
        return chinese_char

    return ''.join([generate_random_chinese() for _ in range(length) ])
 

def image_to_base64(image):
   # 将Image对象保存到字节缓冲区
   img_byte_arr = io.BytesIO()
   image.save(img_byte_arr, format='PNG')  # 可以将图片保存为PNG或其他格式
   img_byte_arr = img_byte_arr.getvalue()
 
   # 使用base64对字节缓冲区进行编码
   img_base64 = base64.b64encode(img_byte_arr)
   return 'data:image/png;base64,' + img_base64.decode('utf-8')

def generate_captcha_image(text=None, font_path=None, font_size=24, width=150, height=50, color=(0, 0, 0)):
    if text is None:
        text = generate_captcha_text()

    body = Image.new('RGB', (width, height), (255, 255, 255))
    thumb =  Image.new('RGB', (int(width/2), int(height/2)), (255, 255, 255))

    tdraw = ImageDraw.Draw(thumb)
    draw = ImageDraw.Draw(body)
    font = ImageFont.load_default() if font_path is None else ImageFont.truetype(font_path, font_size)

    result = list()

    for i in range(len(text)):
        origin_position = (random.randint(int(i*width/len(text)), int(((i+1)*width/len(text)-font_size))), random.randint(0, height-font_size))
        left, top, right, bottom = draw.textbbox(origin_position, text[i], font=font)
        color = (random.randint(0,255), random.randint(0,255), random.randint(0,255) )
        draw.text(origin_position, text[i], fill=color, font=font)

        if (random.randint(0,10) %2 == 0 and len(result) < 2) or (len(result) <2 and i==len(text)-1):
            pos = (int(len(result)*(width/4)), 0)
            result.append(
                {
                    'index': len(result),
                    'x': origin_position[0] + font_size/2,#pos[0],
					'y':origin_position[1] + font_size/2 #0
                }
            )
            ## 绘制
            tdraw.text(pos, text[i], fill=color, font=font)

            
    return image_to_base64(body), image_to_base64(thumb), result


if __name__ == '__main__':
    generate_captcha_image()